{
  /**
   * 2016-01-04 added by re
   * 注册console，解决ie下console报错问题
   * 不必再使用console && console.log(...)来规避ie下console异常
   */
  (function(con) {
    'use strict';
    var prop, method;
    var empty = {};
    var dummy = function() {};
    var properties = 'memory'.split(',');
    var methods = (
      'assert,clear,count,debug,dir,dirxml,error,exception,group,' +
      'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' +
      'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn'
    ).split(',');
    while ((prop = properties.pop())) con[prop] = con[prop] || empty;
    while ((method = methods.pop())) con[method] = con[method] || dummy;
  })((window.console = window.console || {}));

  //IE8扩展Array原型方法
  {
    if (typeof Array.prototype.forEach != 'function') {
      Array.prototype.forEach = function(fn, context) {
        for (var k = 0, length = this.length; k < length; k++) {
          if (
            typeof fn === 'function' &&
            Object.prototype.hasOwnProperty.call(this, k)
          )
            fn.call(context, this[k], k, this);
        }
      };
    }

    if (typeof Array.prototype.map != 'function') {
      Array.prototype.map = function(fn, context) {
        var arr = [];
        if (typeof fn === 'function') {
          for (var k = 0, length = this.length; k < length; k++) {
            arr.push(fn.call(context, this[k], k, this));
          }
        }
        return arr;
      };
    }

    if (typeof Array.prototype.filter != 'function') {
      Array.prototype.filter = function(fn, context) {
        var arr = [];
        if (typeof fn === 'function') {
          for (var k = 0, length = this.length; k < length; k++) {
            fn.call(context, this[k], k, this) && arr.push(this[k]);
          }
        }
        return arr;
      };
    }

    if (typeof Array.prototype.some != 'function') {
      Array.prototype.some = function(fn, context) {
        var passed = false;
        if (typeof fn === 'function') {
          for (var k = 0, length = this.length; k < length; k++) {
            if (passed === true) break;
            passed = !!fn.call(context, this[k], k, this);
          }
        }
        return passed;
      };
    }

    if (typeof Array.prototype.every != 'function') {
      Array.prototype.every = function(fn, context) {
        var passed = true;
        if (typeof fn === 'function') {
          for (var k = 0, length = this.length; k < length; k++) {
            if (passed === false) break;
            passed = !!fn.call(context, this[k], k, this);
          }
        }
        return passed;
      };
    }

    if (typeof Array.prototype.indexOf != 'function') {
      Array.prototype.indexOf = function(searchElement, fromIndex) {
        var index = -1;
        fromIndex = fromIndex * 1 || 0;

        for (var k = 0, length = this.length; k < length; k++) {
          if (k >= fromIndex && this[k] === searchElement) {
            index = k;
            break;
          }
        }
        return index;
      };
    }

    if (typeof Array.prototype.lastIndexOf != 'function') {
      Array.prototype.lastIndexOf = function(searchElement, fromIndex) {
        var index = -1,
          length = this.length;
        fromIndex = fromIndex * 1 || length - 1;

        for (var k = length - 1; k > -1; k -= 1) {
          if (k <= fromIndex && this[k] === searchElement) {
            index = k;
            break;
          }
        }
        return index;
      };
    }

    if (typeof Array.prototype.reduce != 'function') {
      Array.prototype.reduce = function(callback, initialValue) {
        var previous = initialValue,
          k = 0,
          length = this.length;
        if (typeof initialValue === 'undefined') {
          previous = this[0];
          k = 1;
        }

        if (typeof callback === 'function') {
          for (k; k < length; k++) {
            this.hasOwnProperty(k) &&
            (previous = callback(previous, this[k], k, this));
          }
        }
        return previous;
      };
    }

    if (typeof Array.prototype.reduceRight != 'function') {
      Array.prototype.reduceRight = function(callback, initialValue) {
        var length = this.length,
          k = length - 1,
          previous = initialValue;
        if (typeof initialValue === 'undefined') {
          previous = this[length - 1];
          k--;
        }
        if (typeof callback === 'function') {
          for (k; k > -1; k -= 1) {
            this.hasOwnProperty(k) &&
            (previous = callback(previous, this[k], k, this));
          }
        }
        return previous;
      };
    }
  }

  //让jquery1.9之后的版本依然支持$.browser方法
  if (!$.browser) {
    $.browser = {
      mozilla: /firefox/.test(navigator.userAgent.toLowerCase()),
      webkit: /webkit/.test(navigator.userAgent.toLowerCase()),
      opera: /opera/.test(navigator.userAgent.toLowerCase()),
      msie: /msie/.test(navigator.userAgent.toLowerCase()),
    };
  }

  /**
   * MM/dd/yyyy hh:mm TT
   * yyyy-MM-dd hh:mm:ss
   */
  Date.prototype.format = function(fmt) {
    var d = this;
    var zeroize = function(value, length) {
      if (!length) length = 2;
      value = String(value);
      for (var i = 0, zeros = ''; i < length - value.length; i++) {
        zeros += '0';
      }
      return zeros + value;
    };

    return fmt.replace(
      /"[^"]*"|'[^']*'|\b(?:d{1,4}|m{1,4}|yy(?:yy)?|([hHMstT])\1?|[lLZ])\b/g,
      function($0) {
        switch ($0) {
          case 'd':
            return d.getDate();
          case 'dd':
            return zeroize(d.getDate());
          case 'ddd':
            return ['Sun', 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat'][
              d.getDay()
              ];
          case 'dddd':
            return [
              'Sunday',
              'Monday',
              'Tuesday',
              'Wednesday',
              'Thursday',
              'Friday',
              'Saturday',
            ][d.getDay()];
          case 'M':
            return d.getMonth() + 1;
          case 'MM':
            return zeroize(d.getMonth() + 1);
          case 'MMM':
            return [
              'Jan',
              'Feb',
              'Mar',
              'Apr',
              'May',
              'Jun',
              'Jul',
              'Aug',
              'Sep',
              'Oct',
              'Nov',
              'Dec',
            ][d.getMonth()];
          case 'MMMM':
            return [
              'January',
              'February',
              'March',
              'April',
              'May',
              'June',
              'July',
              'August',
              'September',
              'October',
              'November',
              'December',
            ][d.getMonth()];
          case 'yy':
            return String(d.getFullYear()).substr(2);
          case 'yyyy':
            return d.getFullYear();
          case 'h':
            return d.getHours() % 12 || 12;
          case 'hh':
            return zeroize(d.getHours() % 12 || 12);
          case 'H':
            return d.getHours();
          case 'HH':
            return zeroize(d.getHours());
          case 'm':
            return d.getMinutes();
          case 'mm':
            return zeroize(d.getMinutes());
          case 's':
            return d.getSeconds();
          case 'ss':
            return zeroize(d.getSeconds());
          case 'l':
            return zeroize(d.getMilliseconds(), 3);
          case 'L':
            var m = d.getMilliseconds();
            if (m > 99) m = Math.round(m / 10);
            return zeroize(m);
          case 'tt':
            return d.getHours() < 12 ? 'am' : 'pm';
          case 'TT':
            return d.getHours() < 12 ? 'AM' : 'PM';
          case 'Z':
            return d.toUTCString().match(/[A-Z]+$/);
          // Return quoted strings with the surrounding quotes removed
          default:
            return $0.substr(1, $0.length - 2);
        }
      }
    );
  };

  /**
   * 字符串--全部替换
   * @param s1
   * @param s2
   * @returns {string}
   */
  String.prototype.replaceAll = function(s1, s2) {
    return this.replace(new RegExp(s1, 'gm'), s2);
  };

  String.prototype.trim = function() {
    return this.ltrim().rtrim();
  };

  /**
   * 字符串--去除字符串左端空格
   */
  String.prototype.ltrim = function() {
    return this.replace(/(^\s*)/g, '');
  };

  /**
   * 字符串--去除字符串右端空格
   */
  String.prototype.rtrim = function() {
    return this.replace(/(\s*$)/g, '');
  };

  /**
   * 字符串--判断某一个字符串出现在where中次数
   * @param substr
   * @param isIgnore  --是否忽略大小写
   * @returns {*}
   */
  String.prototype.countSubstr = function(substr, isIgnore) {
    var count = 0;
    var reg = '';
    if (isIgnore == true) {
      reg = '/' + substr + '/gi';
    } else {
      reg = '/' + substr + '/g';
    }
    reg = eval(reg);
    if (this.match(reg) != null) {
      count = this.match(reg).length;
    }
    return count;
  };

  Array.prototype.unique = function() {
    var tmpObj = {};
    var tmpArr = [];
    this.forEach(function(item) {
      if (!tmpObj[item]) {
        tmpObj[item] = item;
      }
    });
    for (var key in tmpObj) {
      if (tmpObj.hasOwnProperty(key)) {
        tmpArr.push(tmpObj[key]);
      }
    }
    return tmpArr;
  };
}

/*
通用的组件及函数
*/
if (!$.ecity) $.ecity = {};
if (!$.ecity.top) $.ecity.top = window.parent.$.ecity.top;

(function(o) {
  var K = o.$LAB,
    y = 'UseLocalXHR',
    z = 'AlwaysPreserveOrder',
    u = 'AllowDuplicates',
    A = 'CacheBust',
    B = 'BasePath',
    C = /^[^?#]*\//.exec(location.href)[0],
    D = /^\w+\:\/\/\/?[^\/]+/.exec(C)[0],
    i = document.head || document.getElementsByTagName('head'),
    L =
      (o.opera &&
        Object.prototype.toString.call(o.opera) == '[object Opera]') ||
      'MozAppearance' in document.documentElement.style,
    q = document.createElement('script'),
    E = typeof q.preload == 'boolean',
    r = E || (q.readyState && q.readyState == 'uninitialized'),
    F = !r && q.async === true,
    M = !r && !F && !L;

  function G(a) {
    return Object.prototype.toString.call(a) == '[object Function]';
  }

  function H(a) {
    return Object.prototype.toString.call(a) == '[object Array]';
  }

  function N(a, c) {
    var b = /^\w+\:\/\//;
    if (/^\/\/\/?/.test(a)) {
      a = location.protocol + a;
    } else if (!b.test(a) && a.charAt(0) != '/') {
      a = (c || '') + a;
    }
    return b.test(a) ? a : (a.charAt(0) == '/' ? D : C) + a;
  }

  function s(a, c) {
    for (var b in a) {
      if (a.hasOwnProperty(b)) {
        c[b] = a[b];
      }
    }
    return c;
  }

  function O(a) {
    var c = false;
    for (var b = 0; b < a.scripts.length; b++) {
      if (a.scripts[b].ready && a.scripts[b].exec_trigger) {
        c = true;
        a.scripts[b].exec_trigger();
        a.scripts[b].exec_trigger = null;
      }
    }
    return c;
  }

  function t(a, c, b, d) {
    a.onload = a.onreadystatechange = function() {
      if (
        (a.readyState &&
          a.readyState != 'complete' &&
          a.readyState != 'loaded') ||
        c[b]
      )
        return;
      a.onload = a.onreadystatechange = null;
      d();
    };
  }

  function I(a) {
    a.ready = a.finished = true;
    for (var c = 0; c < a.finished_listeners.length; c++) {
      a.finished_listeners[c]();
    }
    a.ready_listeners = [];
    a.finished_listeners = [];
  }

  function P(d, f, e, g, h) {
    setTimeout(function() {
      var a,
        c = f.real_src,
        b;
      if ('item' in i) {
        if (!i[0]) {
          setTimeout(arguments.callee, 25);
          return;
        }
        i = i[0];
      }
      a = document.createElement('script');
      if (f.type) a.type = f.type;
      if (f.charset) a.charset = f.charset;
      if (h) {
        if (r) {
          e.elem = a;
          if (E) {
            a.preload = true;
            a.onpreload = g;
          } else {
            a.onreadystatechange = function() {
              if (a.readyState == 'loaded') g();
            };
          }
          a.src = c;
        } else if (h && c.indexOf(D) == 0 && d[y]) {
          b = new XMLHttpRequest();
          b.onreadystatechange = function() {
            if (b.readyState == 4) {
              b.onreadystatechange = function() {};
              e.text = b.responseText + '\n//@ sourceURL=' + c;
              g();
            }
          };
          b.open('GET', c);
          b.send();
        } else {
          a.type = 'text/cache-script';
          t(a, e, 'ready', function() {
            i.removeChild(a);
            g();
          });
          a.src = c;
          i.insertBefore(a, i.firstChild);
        }
      } else if (F) {
        a.async = false;
        t(a, e, 'finished', g);
        a.src = c;
        i.insertBefore(a, i.firstChild);
      } else {
        t(a, e, 'finished', g);
        a.src = c;
        i.insertBefore(a, i.firstChild);
      }
    }, 0);
  }

  function J() {
    var l = {},
      Q = r || M,
      n = [],
      p = {},
      m;
    l[y] = true;
    l[z] = false;
    l[u] = false;
    l[A] = false;
    l[B] = '';

    function R(a, c, b) {
      var d;

      function f() {
        if (d != null) {
          d = null;
          I(b);
        }
      }

      if (p[c.src].finished) return;
      if (!a[u]) p[c.src].finished = true;
      d = b.elem || document.createElement('script');
      if (c.type) d.type = c.type;
      if (c.charset) d.charset = c.charset;
      t(d, b, 'finished', f);
      if (b.elem) {
        b.elem = null;
      } else if (b.text) {
        d.onload = d.onreadystatechange = null;
        d.text = b.text;
      } else {
        d.src = c.real_src;
      }
      i.insertBefore(d, i.firstChild);
      if (b.text) {
        f();
      }
    }

    function S(c, b, d, f) {
      var e,
        g,
        h = function() {
          b.ready_cb(b, function() {
            R(c, b, e);
          });
        },
        j = function() {
          b.finished_cb(b, d);
        };
      b.src = N(b.src, c[B]);
      b.real_src =
        b.src +
        (c[A]
          ? (/\?.*$/.test(b.src) ? '&_' : '?_') + ~~(Math.random() * 1e9) + '='
          : '');
      if (!p[b.src])
        p[b.src] = {
          items: [],
          finished: false,
        };
      g = p[b.src].items;
      if (c[u] || g.length == 0) {
        e = g[g.length] = {
          ready: false,
          finished: false,
          ready_listeners: [h],
          finished_listeners: [j],
        };
        P(
          c,
          b,
          e,
          f
            ? function() {
              e.ready = true;
              for (var a = 0; a < e.ready_listeners.length; a++) {
                e.ready_listeners[a]();
              }
              e.ready_listeners = [];
            }
            : function() {
              I(e);
            },
          f
        );
      } else {
        e = g[0];
        if (e.finished) {
          j();
        } else {
          e.finished_listeners.push(j);
        }
      }
    }

    function v() {
      var e,
        g = s(l, {}),
        h = [],
        j = 0,
        w = false,
        k;

      function T(a, c) {
        a.ready = true;
        a.exec_trigger = c;
        x();
      }

      function U(a, c) {
        a.ready = a.finished = true;
        a.exec_trigger = null;
        for (var b = 0; b < c.scripts.length; b++) {
          if (!c.scripts[b].finished) return;
        }
        c.finished = true;
        x();
      }

      function x() {
        while (j < h.length) {
          if (G(h[j])) {
            try {
              h[j++]();
            } catch (err) {}
            continue;
          } else if (!h[j].finished) {
            if (O(h[j])) continue;
            break;
          }
          j++;
        }
        if (j == h.length) {
          w = false;
          k = false;
        }
      }

      function V() {
        if (!k || !k.scripts) {
          h.push(
            (k = {
              scripts: [],
              finished: true,
            })
          );
        }
      }

      e = {
        script: function() {
          for (var f = 0; f < arguments.length; f++) {
            (function(a, c) {
              var b;
              if (!H(a)) {
                c = [a];
              }
              for (var d = 0; d < c.length; d++) {
                V();
                a = c[d];
                if (G(a)) a = a();
                if (!a) continue;
                if (H(a)) {
                  b = [].slice.call(a);
                  b.unshift(d, 1);
                  [].splice.apply(c, b);
                  d--;
                  continue;
                }
                if (typeof a == 'string') {
                  a = {
                    src:
                      window._API_Path && a.trim().indexOf('-/') == 0
                        ? window._API_Path + a.substring(1)
                        : $.ecity.rootpath +
                        (a.indexOf('/') == 0 ? '' : '/') +
                        a,
                  };
                }
                a = s(a, {
                  ready: false,
                  ready_cb: T,
                  finished: false,
                  finished_cb: U,
                });
                k.finished = false;
                k.scripts.push(a);
                S(g, a, k, Q && w);
                w = true;
                if (g[z]) e.wait();
              }
            })(arguments[f], arguments[f]);
          }
          return e;
        },
        wait: function() {
          if (arguments.length > 0) {
            for (var a = 0; a < arguments.length; a++) {
              h.push(arguments[a]);
            }
            k = h[h.length - 1];
          } else k = false;
          x();
          return e;
        },
      };
      return {
        script: e.script,
        wait: e.wait,
        setOptions: function(a) {
          s(a, g);
          return e;
        },
      };
    }

    m = {
      setGlobalDefaults: function(a) {
        s(a, l);
        return m;
      },
      setOptions: function() {
        return v().setOptions.apply(null, arguments);
      },
      script: function() {
        return v().script.apply(null, arguments);
      },
      wait: function() {
        return v().wait.apply(null, arguments);
      },
      queueScript: function() {
        n[n.length] = {
          type: 'script',
          args: [].slice.call(arguments),
        };
        return m;
      },
      queueWait: function() {
        n[n.length] = {
          type: 'wait',
          args: [].slice.call(arguments),
        };
        return m;
      },
      runQueue: function() {
        var a = m,
          c = n.length,
          b = c,
          d;
        for (; --b >= 0; ) {
          d = n.shift();
          a = a[d.type].apply(null, d.args);
        }
        return a;
      },
      noConflict: function() {
        o.$LAB = K;
        return m;
      },
      sandbox: function() {
        return J();
      },
    };
    return m;
  }

  o.$LAB = J();
  (function(a, c, b) {
    if (document.readyState == null && document[a]) {
      document.readyState = 'loading';
      document[a](
        c,
        (b = function() {
          document.removeEventListener(c, b, false);
          document.readyState = 'complete';
        }),
        false
      );
    }
  })('addEventListener', 'DOMContentLoaded');
})(this);

$.ecity.Class = function() {
  var len = arguments.length;
  var P = arguments[0];
  var F = arguments[len - 1];
  var C =
    typeof F.initialize == 'function'
      ? F.initialize
      : function() {
        P.prototype.initialize.apply(this, arguments);
      };
  if (len > 1) {
    var newArgs = [C, P].concat(
      Array.prototype.slice.call(arguments).slice(1, len - 1),
      F
    );
    $.ecity.inherit.apply(null, newArgs);
  } else {
    C.prototype = F;
  }
  return C;
};

/**
 * Function: 继承父类创建子类  $.ecity.inherit({mymethod:function(){}},parentclass);
 * Parameters:
 * C - {Object} 子类对象the class that inherits
 * P - {Object} the superclass to inherit from
 *
 * In addition to the mandatory C and P parameters, an arbitrary number of
 * objects can be passed, which will extend C.
 */
$.ecity.inherit = function(C, P) {
  var F = function() {};
  F.prototype = P.prototype;
  C.prototype = new F();
  var i, l, o;
  for (i = 2, l = arguments.length; i < l; i++) {
    o = arguments[i];
    if (typeof o === 'function') {
      o = o.prototype;
    }
    $.ecity.extend(C.prototype, o);
  }
};

$.ecity.extend = function(destination, source) {
  destination = destination || {};
  if (source) {
    for (var property in source) {
      var value = source[property];
      if (value !== undefined) {
        destination[property] = value;
      }
    }
    var sourceIsEvt =
      typeof window.Event == 'function' && source instanceof window.Event;

    if (
      !sourceIsEvt &&
      source.hasOwnProperty &&
      source.hasOwnProperty('toString')
    ) {
      destination.toString = source.toString;
    }
  }
  return destination;
};

/**
 * 根目录获取，两大类六种场景：
 * 1、jetty、tomcat
 * 1.1 http://localhost:8111/pipenet2.0/index.jsp? --> 传统 jsp，转发使用 proxy.jsp
 * 1.2 http://localhost:8111/pipenet-docker-patrol/? --> 使用 jetty/tomcat 发布的 index.html，转发使用 proxy.jsp
 * 1.3 http://localhost:8111/pipenet-docker-patrol/index.html? --> 使用 jetty/tomcat 发布的 index.html，转发使用 proxy.jsp，等价于场景 1.1
 * 2、nginx
 * 2.1 http://localhost:8891? --> 使用 nginx 发布的 index.html，转发使用 nginx 代理（proxy8889）
 * 2.2 http://localhost:8891/login/user? --> 使用 nginx 发布的 index.html，转发使用 nginx 代理（proxy8889），开启 browser 路由
 * 2.3 http://localhost:8891#login? --> 使用 nginx 发布的 index.html，转发使用 nginx 代理（proxy8889），开启 hash 路由
 *
 * 备注：
 * nginx 模式下，不能出现 http://localhost:8891/login/user/ 这种以斜杠结尾的地址...
 */
$.ecity.rootpath = (function() {
  var scope = $.ecity.top || window;
  var fullPath = scope.document.location.href;
  var pName = scope.document.location.pathname;
  if (pName === '/') {
    // 用于场景 2.x
    return '';
  }
  var pos = fullPath.indexOf(pName);
  var prePath = fullPath.substring(0, pos);
  var postPath = pName.substring(0, pName.substr(1).indexOf('/') + 1);

  if (
    postPath !== '' &&
    (postPath.indexOf('.jsp') || // 用于场景 1.1
      postPath.indexOf('.html') ||
      postPath.indexOf('.htm') || // 用于场景 1.3
      postPath.lastIndexOf('/') === postPath.length - 1) // 用于场景 1.2
  ) {
    return prePath + postPath;
  } else {
    // 用于场景 2.x
    return '';
  }
})();

$.ecity.load = $LAB;
$.ecity.load.css = function() {
  for (var i = 0; i < arguments.length; i++) {
    try {
      var src = arguments[i];
      var csspath =
        window._API_Path && src.trim().indexOf('-/') == 0
          ? window._API_Path + src.substring(1)
          : $.ecity.rootpath + (src.indexOf('/') == 0 ? '' : '/') + src;

      if (document.createStyleSheet) {
        document.createStyleSheet(csspath);
      } else {
        $(
          '<link rel="stylesheet" type="text/css" href="' + csspath + '"/>'
        ).appendTo('head');
      }
    } catch (e) {
      alert(e.message);
    }
  }
};
//同步加载文件
$.ecity.load.script1 = function() {
  if (!$.ecity.load.cacheScirpt) $.ecity.load.cacheScirpt = [];
  for (var i = 0; i < arguments.length; i++) {
    try {
      if ($.ecity.load.cacheScirpt[arguments[i]]) {
        continue;
      }
      $.ecity.load.cacheScirpt[arguments[i]] = arguments[i];
      var src = arguments[i];
      //var jspath = (window._API_Path && src.trim().
      //                                      indexOf("-/") == 0) ? window._API_Path + src.substring(1) : $.ecity.rootpath + (src.indexOf("/") == 0 ? "" : "/") + src;
      if (window._API_Path && src.trim().indexOf('-/') == 0) {
        jspath = window._API_Path + src.substring(1);
      } else {
        jspath = $.ecity.rootpath + (src.indexOf('/') == 0 ? '' : '/') + src;
      }

      var res = $.ajax({
        url: $.ecity.url(jspath),
        async: false,
        type: 'get',
      });
      if (res.status != 200) {
        alert('加载 ' + jspath + ' 时出现异常');
        continue;
      }
      var res0 = res.responseText;
      eval(res0);
    } catch (e) {
      alert(e.name + ': ' + e.message);
    }
  }
};
// 转换url,是否使用代理
$.ecity.url = function(url, useProxy) {
  var _cfg =
    $.ecity.top.$.ecity.frame &&
    $.ecity.top.$.ecity.frame.sysCfg &&
    $.ecity.top.$.ecity.frame.sysCfg.data &&
    $.ecity.top.$.ecity.frame.sysCfg.data.mapcfg &&
    $.ecity.top.$.ecity.frame.sysCfg.data.mapcfg.length !== 0
      ? $.ecity.top.$.ecity.frame.sysCfg.data.mapcfg
      : {
        alwaysUseProxy: true,
        proxy: {
          url: 'proxy.jsp',
        },
      };
  // 2019-03-01 当转发地址配置为空时，proxy.url 会被转换为 0，太诡了，by re
  if (_cfg.proxy.url !== 0 && (useProxy || !!Number(_cfg.alwaysUseProxy))) {
    //var urlProxy = _cfg.proxy.url.replace("../", "");
    //var topHref = $.ecity.top.location.href.split("?")[0].replace("//", "");
    //var winHref = window.location.href.split("?")[0].replace("//", "");
    //var s = winHref.split("/").length - topHref.split("/").length;
    //
    //while (s > 0) {
    //    urlProxy = "../" + urlProxy;
    //    s--;
    //}
    //return urlProxy + "?" + url;

    var urlProxy = _cfg.proxy.url.replace('../', '');
    return $.ecity.rootpath + '/' + urlProxy + '?' + url;
  } else {
    return url;
  }
};
// $.ecity.load.script1("-/frame/js/objectFactory.js");

//网页窗口大小位置计算
$.ecity.window = new (function() {
  this._size = null;
  this._getsize = function() {
    var de = document.documentElement;
    var w =
      window.innerWidth ||
      self.innerWidth ||
      (de && de.clientWidth) ||
      document.body.clientWidth;
    var h =
      window.innerHeight ||
      self.innerHeight ||
      (de && de.clientHeight) ||
      document.body.clientHeight;
    this._size = [w, h];
  };
  this.width = function() {
    this._getsize();
    return this._size[0];
  };
  this.height = function() {
    this._getsize();
    return this._size[1];
  };
  this.left = function() {
    return typeof window.screenLeft == 'number'
      ? window.screenLeft
      : window.screenX;
  };
  this.top = function() {
    return typeof window.screenTop == 'number'
      ? window.screenTop
      : window.screenY;
  };
})();

$.ecity.postWin = new (function() {
  this.post = function(url, target, data) {
    target = target || '_blank';
    var method = data ? 'post' : 'get';
    var $form = $(
      '<form action="' +
      url +
      '" target="' +
      target +
      '" style="display:none" method="' +
      method +
      '"></form>'
    ).appendTo('body');
    if (data) {
      $.each(data, function(key, value) {
        $('<input type="hidden" name="' + key + '"/>')
          .appendTo($form[0])
          .val(value);
      });
    }
    $form.submit();
    setTimeout(function() {
      $form.remove();
    }, 500);

    if (
      target != '_blank' &&
      target != '_self' &&
      target != '_parent' &&
      target != '_top'
    ) {
      $.ecity.top.$.ecity.loading.show();
      $.ecity.postWin.isLoaded(target);
    }
  };
  this.isLoaded = function(target) {
    if (
      $('iframe[name=' + target + ']')[0].contentWindow.document.readyState ==
      'interactive' ||
      $('iframe[name=' + target + ']')[0].contentWindow._loaded
    ) {
      //_loaded是后台写回来的 hcy added
      $.ecity.top.$.ecity.loading.hide();
      return;
    }

    setTimeout(function() {
      $.ecity.postWin.isLoaded(target);
    }, 1000);
  };
  /**
   * 另存为
   * @param url   下载url
   */
  this.$downloadBox = null;
  this.saveAs = function(url) {
    var mask = $.ecity.top.$.ecity.frame.getClass('mask');
    mask.show();
    var winHeight = mask.getSize().height;
    var winWidth = mask.getSize().width;
    var $container = mask.getJqObj();
    var $downloadBox = this.$downloadBox;
    if ($downloadBox) {
      $downloadBox.remove();
    }
    var downloadName = url.substr(url.lastIndexOf('/') + 1, url.length);
    var domain2 = $.ecity.top.$.ecity.rootpath.match(
      /(\w+):\/\/([^/:]+)(:\d*)?/
    );
    var downLoadUrl;
    // 假设这个场景，就是使用 nginx 进行发布，那么 url 一定是可以直接进行下载的
    if (domain2 === null) {
      // 2018-05-22 替换当前下载的路径为系统访问路径， 解决跨域下载问题 by chenhui
      var domain1 = url.match(/(\w+):\/\/([^/:]+)(:\d*)?/);
      downLoadUrl = url.replace(domain1[0], domain2[0]);
    } else {
      downLoadUrl = url;
    }
    $downloadBox = this.$downloadBox = $(
      '<div class="save-as-download-box"></div>'
    )
      .css({
        position: 'absolute',
        left: (winWidth - 500) / 2,
        top: (winHeight - 300) / 2,
        width: 500,
        height: 300,
        background: '#FFFFFF',
      })
      .appendTo($container);

    $("<div class='save-as-bb'></div>")
      .css({
        position: 'absolute',
        width: 10,
        height: 30,
        bgColor: '#20B888',
        top: 8,
      })
      .appendTo($downloadBox);

    $("<div class='save-as-name'>")
      .css({
        maxWidth: 350,
        position: 'absolute',
        fontSize: 20,
        top: 10,
        left: 30,
        overflow: 'hidden',
        whiteSpace: 'nowrap',
        textOverflow: 'ellipsis',
      })
      .text(downloadName)
      .appendTo($downloadBox);
    $("<span id='save-as-close'>×</span>")
      .css({
        fontSize: 30,
        marginLeft: 465,
        color: '#7F7F7F',
        width: 30,
        height: 30,
        cursor: 'pointer',
      })
      .mouseover(function() {
        $(this).css({
          color: '#19A97B',
          cursor: 'pointer',
        });
      })
      .mouseout(function() {
        $(this).css({
          color: '#7F7F7F',
        });
      })
      .click(function() {
        $downloadBox.remove();
        mask.close();
      })
      .appendTo($downloadBox);

    $downloadBox.append(
      "<hr style='width: 460px;color: #D2D2D2;opacity:0.3;margin-left: 20px;margin-top: 10px;'>"
    );
    $("<a class='save-as-download-btn'>下  载</a>")
      .css({
        position: 'absolute',
        marginLeft: 210,
        marginTop: 85,
        width: 80,
        height: 40,
        textAlign: 'center',
        lineHeight: '38px',
        borderRadius: 2,
        color: '#fafafa',
        bgColor: '#20B888',
        textDecoration: 'none',
      })
      .mouseover(function() {
        $(this).css({
          bgColor: '#7F7F7F',
          cursor: 'pointer',
        });
      })
      .mouseout(function() {
        $(this).css({
          bgColor: '#20B888',
        });
      })
      .attr({
        href: downLoadUrl,
        target: '_blank',
        title: '请直接点击或鼠标右键转下载工具打开，不要拖拽到下载工具悬浮框中',
      })
      .appendTo($downloadBox);

    //var dialogId = 'save-as-' + new Date().getMilliseconds();
    //$.ecity.top.$.ecity.dialog.show({
    //    id: dialogId,
    //    title: "另存为",
    //    width: 80,
    //    height: 45,
    //    left: 60,
    //    top: 85,
    //    content: '<div style="cursor: default; height: 100%; width:100%; padding-top:15px; text-align: center;">' +
    //    '<a style="text-decoration: underline; cursor: pointer; color: #00F;" ' +
    //    'title="请直接点击或鼠标右键转下载工具打开，请不要拖拽到下载工具悬浮框中"' +
    //    'target="_blank" ' +
    //    'href="' + downloadUrl + '">下载</a>' +
    //    '</div>',
    //    minable: false,
    //    maxable: false
    //});
  };
})();

$.ecity.error = new (function() {
  this.validate = function(value) {
    if (value === '' || value === null || value === undefined || value.error) {
      return true;
    }
  };
  this.show = function(value, time) {
    var message = null;
    if (value && value.error && value.error.message) {
      message = value.error.message;
    } else {
      message = '服务异常，返回为空';
      console.error(value);
    }
    time = time || 2000;
    $.ecity.dialog.message(message, time);
  };
})();

/*拖拽jQuery对象,封装为动态加载接口,给dom应用后可以拖拽dom节点*/
$.fn.dragable = function(options) {
  return this.each(function() {
    if (!$.fn.dragDrop) {
      var thisObj = this;
      $.ecity.load.script('-/frame/ctrlib/dragable.js').wait(function() {
        $(thisObj).dragDrop(options);
      });
    } else {
      $(this).dragDrop(options);
    }
  });
};
/*给元素添加iframe遮盖,解决input不能激活问题,和三维控件遮挡问题*/
$.fn.bgMask = function(options) {
  return this.each(function() {
    if (!$.fn.bgiframe) {
      var thisObj = this;
      $.ecity.load.script('-/frame/ctrlib/jquery.bgiframe.js').wait(function() {
        $(thisObj).bgiframe(options);
      });
    } else {
      $(this).bgiframe(options);
    }
  });
};

//翻转组件
$.ecity.flip = new (function() {
  this._sDeg = 270;
  this._dDeg = 360;
  this._i = 1;
  this._zHeight = 1000;
  this.time = 90;

  this.set3D = function(elem, deg, dir) {
    deg = deg || this._sDeg;
    dir = dir || '';
    elem.css(
      '-webkit-transform',
      'perspective(' + this._zHeight + 'px) rotate' + dir + '(' + deg + 'deg)'
    );
    elem.css(
      '-moz-transform',
      'perspective(' + this._zHeight + 'px) rotate' + dir + '(' + deg + 'deg)'
    );
    elem.css(
      'transform',
      'perspective(' + this._zHeight + 'px) rotate' + dir + '(' + deg + 'deg)'
    );
    elem.css('transform-origin', 'bottom');
    //elem.css("transformOrigin", "bottom");
  };
  this.flip3D = function(options) {
    var elem = options.elem,
      startDeg = options.startDeg,
      endDeg = options.endDeg,
      callback = options.callback,
      addDeg = options.addDeg,
      dir = options.dir;
    addDeg = addDeg || 20;
    dir = dir || '';
    var thisObj = this;
    setTimeout(function() {
      var deg = 0;
      if (startDeg > endDeg) {
        deg =
          startDeg - thisObj._i * addDeg < endDeg
            ? endDeg
            : startDeg - thisObj._i * addDeg;
      } else {
        deg =
          thisObj._i * addDeg + startDeg > endDeg
            ? endDeg
            : thisObj._i * addDeg + startDeg;
      }
      thisObj._i++;
      elem.css(
        '-webkit-transform',
        'perspective(' +
        thisObj._zHeight +
        'px) rotate' +
        dir +
        '(' +
        deg +
        'deg)'
      );
      elem.css(
        '-moz-transform',
        'perspective(' +
        thisObj._zHeight +
        'px) rotate' +
        dir +
        '(' +
        deg +
        'deg)'
      );
      elem.css(
        'transform',
        'perspective(' +
        thisObj._zHeight +
        'px) rotate' +
        dir +
        '(' +
        deg +
        'deg)'
      );
      elem.css('transform-origin', 'bottom');

      if (
        (startDeg < endDeg && deg >= endDeg) ||
        (startDeg > endDeg && deg <= endDeg)
      ) {
        thisObj._i = 1;
        if (callback) callback(elem);
      } else {
        thisObj.flip3D(options);
      }
    }, thisObj.time);
  };
})();

/*
*弹出对话框
*title:标题,left:,top:,width:,height:,
*url:网页地址,
*content:内容,div、span等,
*onClose:function(dialog){},关闭回调
*对话框的传入参数可以在页面上配置,格式为在head中添加一个json描述:dialog_style,还可以根据菜单项改变属性
function set_dialog_style(){
}
示例：
<script>
dialog_style = {
id: "query_line",
title: "沿线查询w",
width: 215,
height: 120,
left: 350,
top: 278,
minable: false,
maxable: false,
onClose: function () {
$.ecity.mapWnd.mapDisplay.removeLayer("lineQuery");
$.ecity.mapWnd.mapDisplay.removeLayer("alongline");
$.ecity.mapWnd.textSymbol.remove("lineQuery_pnt1");
$.ecity.mapWnd.textSymbol.remove("lineQuery_pnt2");
}
};

function set_dialog_style(params){

}
</script>
*在对话框页面中获取外面传入的参数:window._dialog.params,通过对话框获取页面窗体:dialog.wnd
*/
$.ecity.dialog = new (function() {
  var currentDlg = '$.dlgCommon';
  var getPosition = function(options) {
    var position = {};
    var left = options.left;
    var right = options.right;
    var top = options.top;
    var bottom = options.bottom;
    // 左右
    if (typeof left === 'number') {
      position.left = options.left;
    } else if (typeof right === 'number') {
      position.right = options.right;
    }

    // 上下
    if (typeof top === 'number') {
      position.top = options.top;
    } else if (typeof bottom === 'number') {
      position.bottom = options.bottom;
    }
    return position;
  };

  var getCurrentDlg = function() {
    var dlgStyle = '';
    try {
      dlgStyle = $.ecity.top.$.ecity.frame.sysCfg.data.init.defaultDialogStyle;
    } catch (e) {
      dlgStyle = '';
    }

    if (dlgStyle && dlgStyle.length > 0) {
      currentDlg = '$.' + dlgStyle;
    }
  };

  this.message = function(message, time, width, height) {
    getCurrentDlg();
    var p = {
      title: '提示',
      width: width || 260,
      height: height || 70,
      closeable: true,
      maxable: false,
      draggable: true,
      time: time || 2000,
      content:
        "<div style='padding:20px;text-align:center;'>" + message + '</div>',
    };
    $.ecity.top.$.ecity.new0(
      currentDlg,
      function(dialog) {
        dialog.show();
      },
      p
    );
  };

  this.confirm = function(message, ok, cancel, options) {
    var defaultOptions = {
      title: '确认',
      width: 260,
      height: 70,
      closeable: false,
      btnpos: 'center',
      maxable: false,
      content:
        "<div style='padding:20px;text-align:center;'>" + message + '</div>',
    };
    defaultOptions.buttons = [
      {
        text: '确定',
        handler: function(dlg) {
          ok(dlg);
        },
      },
      {
        text: '取消',
        handler: function(dlg) {
          cancel(dlg);
        },
      },
    ];
    var p = $.extend(defaultOptions, options);

    getCurrentDlg();
    $.ecity.top.$.ecity.new0(
      currentDlg,
      function(dialog) {
        dialog.show();
      },
      p
    );
  };
  this.show = function(options) {
    if (options.url) {
      var p0 = this.getDialogStyle(options);
      if (p0) {
        if (options.force) {
          options = $.extend(p0, options);
        } else {
          options = $.extend(options, p0);
        }
      }
    }
    var defaultOptions = {
      draggable: true,
      overlay: false,
      minable: false,
      maxable: true,
      closeable: true,
    };

    var p = $.extend(defaultOptions, options);
    p.width = p.width || 500;
    p.height = p.height || 320;
    p.position = getPosition(p);

    if (options.url) {
      p.content =
        '<iframe id="' +
        options.id +
        '-iframe" frameborder="0"  src="' +
        options.url +
        '" style="width:100%;height:100%;"></iframe>';
    } else if (options.noHtml) {
      p.content =
        '<div id="dialog-func-container-' +
        options.id +
        '" style="width:100%;height:100%;"></div>';
    }

    getCurrentDlg();
    $.ecity.top.$.ecity.new0(
      currentDlg,
      function(dialog) {
        dialog.show();
      },
      p
    ); //wnd = wnd.getContent().find("iframe")[0].contentWindow;
  };
  this.showBlue = function(options) {
    if (options.url) {
      var p0 = this.getDialogStyle(options);
      p0 && (options = $.extend(options, p0));
    }
    var p = $.extend(
      {
        draggable: true,
        overlay: false,
        minable: false,
        maxable: true,
        closeable: true,
      },
      options
    );
    p.width = p.width || 500;
    p.height = p.height || 320;

    p.position = getPosition(p);

    if (options.url) {
      p.content =
        '<iframe id="' +
        options.id +
        '" frameborder="0"  src="' +
        options.url +
        '" style="width:100%;height:100%;"></iframe>';
    }
    $.ecity.top.$.ecity.new0(
      '$.dlgBlue',
      function(dialog) {
        dialog.show();
      },
      p
    );
  };
  this.getDialogStyle = function(options) {
    try {
      var url = options.url;
      url = url.indexOf('/') == 0 ? $.ecity.rootpath + url : url;
      var res = $.ajax({
        url: url,
        async: false,
        type: 'get',
        dataType: 'xml',
      });
      if (res.status != 200) {
        alert(res.status + ' ' + res.statusText + ' ' + url);
        return;
      }
      res = res.responseText;
      //2016-05-18 统一弹框中功能样式的获取方式, 以 view_style 为准
      var viewStyleIndex = res.indexOf('view_style');
      if (viewStyleIndex > -1) {
        res = res.substring(viewStyleIndex);
        res = res.substring(0, res.indexOf('/script>') - 1);
        eval(res);
        try {
          if (typeof set_view_style === 'function') {
            set_view_style(options);
          }
        } catch (err) {
          console.error(err.message);
        }
        var retviewsytle = view_style;
        delete view_style;
        delete set_view_style;
        return retviewsytle;
      } else {
        var index = res.indexOf('dialog_style');
        if (index > -1) {
          res = res.substring(index);
          res = res.substring(0, res.indexOf('/script>') - 1);
          eval(res);
          try {
            if (typeof set_dialog_style === 'function') {
              set_dialog_style(options);
            }
          } catch (err) {
            console.error(err.message);
          }
          var retstyle = dialog_style;
          delete dialog_style;
          delete set_dialog_style;
          return retstyle;
        }
      }
      return null;
    } catch (err) {
      console.error(err.message);
      return null;
    }
  };
  this.getDialog = function(id) {
    var obj = null;
    if ($.dlgBase && $.dlgBase.listDlg) {
      obj = $.dlgBase.listDlg[id];
    }
    return obj;
  };
  this.showOrHideDlgs = function(opend) {
    if ($.dlgBase && $.dlgBase.listDlg) {
      for (var v in $.dlgBase.listDlg) {
        if ($.dlgBase.listDlg[v] && $.dlgBase.listDlg[v].visible && opend) {
          $.dlgBase.listDlg[v].visible(1);
        } else if (
          $.dlgBase.listDlg[v] &&
          $.dlgBase.listDlg[v].visible &&
          !opend
        ) {
          $.dlgBase.listDlg[v].visible();
        }
      }
    }
  };
})();

$.fn.sliders = function(options) {
  var options = options || {};
  return this.each(function() {
    if (!$.fn.slider) {
      var thisObj = this;
      $.ecity.load.css('-/frame/ctrlib/slider/bin/jquery.slider.min.css');
      $.ecity.load
        .script('-/frame/ctrlib/slider/bin/jquery.slider.min.js')
        .wait(function() {
          $(thisObj).slider(options);
        });
    } else {
      $(this).slider(options);
    }
  });
};
$.fn.jscrolls = function(options) {
  var options = options || {};
  return this.each(function() {
    if (!$.fn.jscroll) {
      var thisObj = this;
      $.ecity.load.script('-/frame/ctrlib/jscroll.js').wait(function() {
        $(thisObj).jscroll(options);
      });
    } else {
      $(this).jscroll(options);
    }
  });
};
$.fn.perfectScrollbars = function(options) {
  var options = options || {};
  return this.each(function() {
    if (!$.fn.perfectScrollbar) {
      var thisObj = this;
      $.ecity.load.css(
        '-/frame/ctrlib/perfect-scrollbar/src/perfect-scrollbar.css'
      );
      $.ecity.load
        .script('-/frame/ctrlib/perfect-scrollbar/src/perfect-scrollbar.js')
        .wait(function() {
          $(thisObj).perfectScrollbar(options);
        });
    } else {
      $(this).perfectScrollbar(options);
    }
  });
};

$.ecity.getPageParam = function(key, href) {
  //获取URL传递过来的参数
  var input = document.location.href.split('?')[1];
  if (href) {
    input = href.split('?')[1];
  }
  if (!input) {
    return '';
  }

  var result = input.replace(/\?/g, ' ').replace(/\&/g, ' ');
  var items = result.split(' ');
  var m = new RegExp('^' + key + '=', 'i');
  var param = '';
  for (var i = 0; i < items.length; i++) {
    var temp = items[i];
    temp = temp.replace(/\s/g, '');
    if (temp == '') continue;
    if (temp.match(m)) {
      if (param != '') param += ',';
      param += temp.replace(m, '');
    }
  }
  return param;
};
/**
 *isfunctionstr表示函数是否序列化
 */
$.ecity.Json2String = function(O, isfunctionstr) {
  var S = [];
  var J = '';
  if (Object.prototype.toString.apply(O) === '[object Array]') {
    for (var i = 0; i < O.length; i++)
      S.push($.ecity.Json2String(O[i], isfunctionstr));
    J = '[' + S.join(',') + ']';
  } else if (Object.prototype.toString.apply(O) === '[object Date]') {
    J = 'new Date(' + O.getTime() + ')';
  } else if (
    Object.prototype.toString.apply(O) === '[object RegExp]' ||
    Object.prototype.toString.apply(O) === '[object Function]'
  ) {
    J = O.toString();
  } else if (Object.prototype.toString.apply(O) === '[object Object]') {
    for (var i in O) {
      if (typeof O[i] === 'function' && !isfunctionstr) continue;
      var v =
        typeof O[i] == 'string'
          ? JSON.stringify(O[i])
          : $.ecity.Json2String(O[i], isfunctionstr); //(typeof (O[i]) === 'object' ? $.ecity.Json2String(O[i]) : O[i]);//'"' + O[i] + '"'
      S.push(i + ':' + v);
    }
    J = '{' + S.join(',') + '}';
  } else {
    J = O;
  }
  return J;
};

$.ecity.xml2json = function(xml, extended) {
  if (!xml) return {};
  var __parseXML = function(node, simple, extended) {
    if (!node) return null;
    var txt = '',
      obj = null,
      att = null;
    var nt = node.nodeType,
      nn = jsVar(node.localName || node.nodeName);
    var nv = node.text || node.nodeValue || '';
    if (node.childNodes) {
      if (node.childNodes.length > 0) {
        $.each(node.childNodes, function(n, cn) {
          var cnt = cn.nodeType,
            cnn = jsVar(cn.localName || cn.nodeName);
          var cnv = cn.text || cn.nodeValue || '';
          if (cnt == 8) {
            return;
          } else if (cnt == 3 || cnt == 4 || !cnn) {
            if (cnv.match(/^\s+$/)) {
              return;
            }
            txt += cnv.replace(/^\s+/, '').replace(/\s+$/, '');
          } else {
            obj = obj || {};
            if (obj[cnn]) {
              if (!obj[cnn].length) obj[cnn] = myArr(obj[cnn]);
              obj[cnn] = myArr(obj[cnn]);

              obj[cnn][obj[cnn].length] = __parseXML(cn, true);
              obj[cnn].length = obj[cnn].length;
            } else {
              obj[cnn] = __parseXML(cn);
            }
          }
        });
      }
    }
    if (node.attributes) {
      if (node.attributes.length > 0) {
        att = {};
        obj = obj || {};
        $.each(node.attributes, function(a, at) {
          var atn = jsVar(at.name),
            atv = at.value;
          att[atn] = atv;
          if (obj[atn]) {
            obj[cnn] = myArr(obj[cnn]);

            obj[atn][obj[atn].length] = atv;
            obj[atn].length = obj[atn].length;
          } else {
            obj[atn] = !isNaN(atv) ? Number(atv) : atv;
          }
        });
      }
    }
    if (obj) {
      obj = $.extend(txt != '' ? new String(txt) : {}, obj || {});
      txt = obj.text
        ? (typeof obj.text == 'object' ? obj.text : [obj.text || '']).concat([
          txt,
        ])
        : txt;
      if (txt) obj.text = txt;
      txt = '';
    }
    var out = obj || txt;
    if (extended) {
      if (txt) out = {};
      txt = out.text || txt || '';
      if (txt) out.text = txt;
      if (!simple) out = myArr(out);
    }
    return out;
  };
  var jsVar = function(s) {
    return String(s || '').replace(/-/g, '_');
  };
  var myArr = function(o) {
    if (!$.isArray(o)) o = [o];
    o.length = o.length;
    return o;
  };

  if (typeof xml == 'string') xml = $.ecity.text2xml(xml);
  if (!xml.nodeType) return;
  if (xml.nodeType == 3 || xml.nodeType == 4) return xml.nodeValue;

  var root = xml.nodeType == 9 ? xml.documentElement : xml;
  var out = __parseXML(root, true, extended);
  xml = null;
  root = null;
  return out;
};
$.ecity.text2xml = function(str) {
  var xml;
  var out;
  try {
    // if (typeof ActiveXObject === 'function') {
    //     xml = new ActiveXObject("Microsoft.XMLDOM");
    // }
    // else if (typeof DOMParser === 'function') {
    //     xml = new DOMParser();
    // }
    xml = new DOMParser();
    xml.async = false;
  } catch (e) {
    console.error(str);
    throw new Error('XML Parser could not be instantiated');
  }
  try {
    if (typeof xml.load === 'function') {
      out = xml.load(str);
    } else if (typeof xml.parseFromString === 'function') {
      out = xml.parseFromString(str, 'text/xml');
    }
  } catch (e) {
    console.error(str);
    throw new Error('Error parsing XML string');
  }
  return out;
};

/**
 * 如果跟目录下只有一个数组把数组直接归为跟目录,
 * 假如孩子只有一个，这个孩子同时在对象和数组中出现
 * @param obj
 * @returns {*}
 */
$.ecity.jsonArr2Obj = function(obj) {
  var p = null;
  var cnt = 0;
  for (var property in obj) {
    if (obj[property] instanceof Array) {
      p = property;
      cnt++;
    }
  }
  if (cnt == 1) {
    var ret = [].concat(obj[p]);
    for (var property in obj) {
      ret[property] = obj[property];
    }
    mObjs(ret);
    if (ret.key) {
      var prekey = ret.prekey || '';
      for (var i = 0; i < ret.length; i++) {
        if (ret.value && ret.value.length > 0) {
          ret[prekey + ret[i][ret.key]] = ret[i][ret.value];
        } else {
          ret[prekey + ret[i][ret.key]] = ret[i];
        }
      }
    }
    obj = ret;
  } else {
    mObjs(obj);
  }

  function mObjs(o) {
    for (var i = 0; i < o.length; i++) {
      mObjs(o[i]);
    }
    for (var property in o) {
      var att = o[property];
      if (
        !parseInt(property) &&
        parseInt(property) != 0 &&
        typeof att == 'object' &&
        !(att instanceof Array)
      ) {
        var a = [att];
        for (var b in att) {
          a[b] = att[b];
        }
        o[property] = a;
        mObjs(o[property]);
      }
    }
  }

  return obj;
};

/**
 * 异步加载, 同时使用了 jsonArr2Obj() 进行二次加工
 * @param url
 * @param callback
 */
$.ecity.getXmlJson = function(url, callback) {
  $.get(url, function(xml) {
    var obj = $.ecity.xml2json(xml);
    obj = $.ecity.jsonArr2Obj(obj);
    callback(obj);
  });
};

/**
 * 同步加载, 同时使用了 jsonArr2Obj() 进行二次加工
 * @param url
 * @returns {{}}
 */
$.ecity.getXmlJson1 = function(url) {
  var xml = $.ajax({
    url: url,
    async: false,
    type: 'get',
  });
  var obj = $.ecity.xml2json(xml.responseText);
  obj = $.ecity.jsonArr2Obj(obj);
  return obj;
};

/**
 * 异步加载
 * @param url
 * @param callback
 */
$.ecity.getXmlJsonByAsync = function(url, callback) {
  $.get(url, function(xml) {
    var obj = $.ecity.xml2json(xml);
    callback(obj);
  });
};
/**
 * 同步加载
 * @param url
 * @returns {{}}
 */
$.ecity.getXmlJsonBySync = function(url) {
  var xml = $.ajax({
    url: url,
    async: false,
    type: 'get',
  });
  return $.ecity.xml2json(xml.responseText);
};

/**
 * 同步加载
 * @param url
 * @param params
 * @returns {*}
 */
$.ecity.get1 = function(url, params) {
  var res = null;
  var xhr = $.ajax({
    url: url,
    async: false,
    type: 'get',
    data: params,
  });
  if (xhr.status === 200) {
    res = JSON.parse(xhr.responseText);
  }
  return res;
};

$.ecity.getToken = function(forUrl) {
  var url = $.ecity.url('');
  if (url.length == 0) {
    return '';
  }
  return $.ecity.get1(url, {
    forurl: forUrl,
  });
};

/**
 * 2015-09-04 Created by re
 * 查询方法
 */
$.ecity.query = new (function() {
  this.simple = function(options) {
    var params = {
      serverUrl: options.url,
      attTableName: options.tableName,
      $dg: options.$dg,
      paging: 'none',
      rowFields: options.rowFields,
    };
    execTask(params);
  };
  this.falsePaging = function(options) {
    var params = {
      serverUrl: options.url,
      attTableName: options.tableName,
      $dg: options.$dg,
      paging: 'false',
      rowFields: options.rowFields,
      pagesize: options.pagesize,
    };
    execTask(params);
  };
  this.truePaging = function(options) {
    var params = {
      serverUrl: options.url,
      attTableName: options.tableName,
      $dg: options.$dg,
      paging: 'true',
      rowFields: options.rowFields,
      pagesize: options.pagesize,
    };
    execTask(params);
  };
  this.base = function(options) {
    execTask(options);
  };
  var execTask = function(params) {
    $.ecity.top.$.ecity.new0(
      'queryTask.tableQueryTask',
      $.noop(),
      'queryTask',
      params
    );
  };
})();

$.ecity.isObject = function(obj) {
  return Object.prototype.toString.call(obj) == '[object Object]';
};

$.ecity.isArray = function(arr) {
  return Object.prototype.toString.call(arr) == '[object Array]';
};

$.fn.serializeObject = function() {
  var o = {};
  var arr = this.serializeArray();
  arr.forEach(function(item) {
    if (o[item.name]) {
      if (!o[item.name].push) {
        o[item.name] = [o[item.name]];
      }
      o[item.name].push(item.value || '');
    } else {
      o[item.name] = item.value || '';
    }
  });
  return o;
};

/**
 * 2016-04-05 Created by re
 * 等待框
 */
$.ecity.loading = new (function() {
  this.callback = null;
  this.timeout = null;
  this.show = function(message, time, callback) {
    var thisObj = this;
    this.callback = null;
    this.timeout = null;
    if (typeof time == 'function') {
      this.callback = time;
    }
    if (typeof callback == 'function') {
      this.callback = callback;
    }
    if (typeof message == 'number') {
      time = message;
      message = null;
    }
    if ($('.loading1').length == 0) {
      message = message || '数据加载中...';
      this._create(message);
    } else {
      $('#loading1_c').html(
        '&nbsp;&nbsp;&nbsp;' + (message || '数据加载中...')
      );
      $('.loadingMask').show();
    }
    $('.loading1')
      .css({
        left: $.ecity.window.width() / 2 - 120,
        top: $.ecity.window.height() / 2 - 40,
        position: 'absolute',
        zIndex: 9900,
      })
      .show();

    if (time) {
      this.timeout = setTimeout(function() {
        $('.loading1').fadeOut();
        $('.loadingMask') && $('.loadingMask').hide();
        thisObj.callback && thisObj.callback();
      }, time);
    }
  };
  this._create = function(msg) {
    var imgUrl = $.ecity.rootpath + '/images/loading.gif';
    var markup = [
      '<div class="loading1" style="display: none;">',
      '    <div class="loading1-bg ealpha"></div>',
      '    <div class="loading1-content" style="position: absolute;left: 40px;top: 14px; width: 200px;">',
      '         <table><tr><td><img src="' + imgUrl + '" /></td>',
      '         <td id="loading1_c">&nbsp;&nbsp;&nbsp;',
      msg,
      '</td></tr></table>',
      '    </div>',
      '</div>',
      '<div class="loadingMask"></div>',
    ].join('');
    $(markup).appendTo('body');

    $('.loading1-bg.ealpha').css({
      position: 'absolute',
      width: 250,
      height: 65,
      fontSize: '14px',
      boxShadow: '0 5px 10px rgba(0, 0, 0, 0.2)',
      border: '1px solid rgba(0, 0, 0, 0.2)',
      bgColor: '#cfe5f7',
      borderRadius: '6px',
    });

    $('.loadingMask').css({
      zIndex: 9800,
      position: 'absolute',
      left: 0,
      top: 0,
      bottom: 0,
      right: 0,
      bgColor: '#e5e5e5',
      borderRadius: 4,
      opacity: 0.3,
      display: 'block',
    });
  };
  this.hide = function() {
    $('.loading1').fadeOut();
    $('.loadingMask').hide();
    if (this.timeout) {
      clearTimeout(this.timeout);
    }
  };
})();

/**
 * 检查配置文件版本
 * @param cfg               配置文件
 * @param minimumVersion    功能所需最低版本
 * @returns {boolean}
 */
$.ecity.checkVersion = function(cfg, minimumVersion) {
  var flag = false;
  if (typeof cfg !== 'object') {
    console.error('cfg is not object');
    return flag;
  }
  var cfgVersion = cfg.ecityversion;
  if (typeof cfgVersion !== 'string') {
    console.error('cfgVersion is not string');
    return flag;
  }
  if (typeof minimumVersion !== 'string') {
    console.error('toolVersion is not string');
    return flag;
  }
  cfgVersion = parseFloat(cfgVersion.replace('.', '').replace('.', ''));
  minimumVersion = parseFloat(minimumVersion.replace('.', '').replace('.', ''));

  if (isNaN(cfgVersion)) {
    console.error('cfgVersion 不能转换为数字型');
    return flag;
  }
  if (isNaN(minimumVersion)) {
    console.error('minimumVersion 不能转换为数字型');
    return flag;
  }
  if (cfgVersion >= minimumVersion) {
    flag = true;
  }

  return flag;
};

/**
 * 通用上传附件方法
 * @param url       上传 url 路径
 * @param $form     jquery 对象
 * @param callback
 */
$.ecity.uploadFileForm = function(url, $form, callback) {
  $.ecity.load.script('-/frame/js/jquery.form.js').wait(function() {
    if ($form.find("input[name='attachment']").val().length == 0) {
      $.ecity.dialog.message('请选择要上传的文件!');
      return;
    }
    var options = {
      url: $.ecity.url(url), //后台的处理,也就是form里的action
      type: 'post',
      dataType: 'html', //数据格式,有xml,html,json,默认为文本
      success: function(res) {
        try {
          var resStr = res
            .substring(res.indexOf('>') + 1)
            .replace('</pre>', '');
          var resObj = eval('(' + resStr + ')');
          callback && callback(resObj);
        } catch (e) {
          console.log(url);
          console.log(e);
        }
      },
      error: function(response, option, e) {
        $.ecity.dialog.message('上传失败:' + e);
      },
    };
    $form.attr('action', url);
    $form.ajaxSubmit(options);
  });
};

/**
 *
 * @param name - taskServices.xml中name对应字段
 * @returns {string|null}
 * @description 根据name找到taskServices.xml中对应的url
 */
$.ecity.getServiceByName0 = function(name) {
  var serviceCfgs = $.ecity.frame.sysCfg.data.servicecfg.taskservice;
  for (var i = 0; i < serviceCfgs.length; i++) {
    var service = serviceCfgs[i];
    if (name === service.name) {
      return service.url;
    }
  }
  return null;
};

/**
 *
 * @param name - taskServices.xml中name对应字段
 * @returns {*}
 * @description 子级服务name = 父级服务name + '_XXX'，如果当前服务name没有找到对应的url,则往前回溯找父级服务的url，直到找到为止
 */
$.ecity.getNextService = function(name) {
  var index = name.lastIndexOf('_');
  if (index < 0) {
    return $.ecity.getServiceByName0(name);
  } else {
    var splitName = name.substring(0, index);
    var result = $.ecity.getServiceByName0(splitName);
    if (!result) {
      return $.ecity.getNextService(splitName);
    } else {
      return result;
    }
  }
};

/**
 *
 * @param name
 * @returns {*}
 * @description 如果当前name匹配到了url，直接返回；否则回溯父级name,直到找到或者返回为空为止
 */
$.ecity.getServiceByName = function(name) {
  var serviceUrl = $.ecity.getServiceByName0(name);
  if (!serviceUrl) {
    var resUrl = $.ecity.getNextService(name);
    if (!resUrl) {
      console.error('未找到匹配的服务');
    }
    return resUrl;
  } else {
    return serviceUrl;
  }
};

/**
 * 2019-01-26 added by zhouqian
 * 对where条件的拼接，目前主要针对oracle和sql对时间的处理
 * @param {object} params
 * @param {string} params.where -查询条件例如where 日期 < $$(日期1)$$ and 日期> $$(日期2)$$
 * @param {object} params.rule -条件rule:{'日期1':{value:'2019-01-01 00:00:00',name:'日期'},'日期2':{value:'2019-01-01 23:59:59',name:'日期'}}
 * @param {string} params.svr -当前请求的 svr , 对应 taskservice.xml 中 的 name
 * @param {object[]} params.fields -where 语句中所有包含的字段的信息，字段信息格式即为元数据返回的结构
 */
$.ecity.whereCondition = function(params) {
  params = params || {};
  var fieldNameRegExp = /\$\$\S(.+?)\S\$\$/g;
  var fieldsType = params.fields || [];
  var rule = params.rule;
  var _cfg =
    ($.ecity.top.$.ecity.frame &&
      $.ecity.top.$.ecity.frame.sysCfg &&
      $.ecity.top.$.ecity.frame.sysCfg.data &&
      $.ecity.top.$.ecity.frame.sysCfg.data.servicecfg &&
      $.ecity.top.$.ecity.frame.sysCfg.data.servicecfg.taskservice) ||
    [];
  var database = 'sql';
  var result;
  var parsedExp = params.where;
  if (!params.rule) {
    return parsedExp;
  }
  if (!params.svr) {
    _cfg.forEach(function(item) {
      if (item.name === params.svr && params.database) {
        database = params.database;
      }
    });
  }
  while ((result = fieldNameRegExp.exec(params.where)) !== null) {
    var fieldType = '';
    if (rule[result[1]]) {
      console.log('当前站位符位置为空');
    }
    var paramsdata = rule[result[1]] || { name: '', value: '' };
    for (var i = 0; i < fieldsType.length; i++) {
      if (paramsdata.name == fieldsType[i].name) {
        fieldType = fieldsType[i].esritype;
      }
    }
    if (fieldType === '') {
      console.log(paramsdata.name + '没有匹配到该字段');
    }
    if (fieldType === 'esriFieldTypeDate' && database === 'oracle') {
      var value = "to_date('" + paramsdata.value + "','yyyy-mm-dd hh24:mi:ss')";
      parsedExp = parsedExp.replace(result[0], value);
    } else if (fieldType === 'esriFieldTypeDate' && database === 'arcgis') {
      var value1 = 'date' + paramsdata.value;
      parsedExp = parsedExp.replace(result[0], value1);
    } else {
      parsedExp = parsedExp.replace(result[0], paramsdata.value);
    }
  }
  return parsedExp;
};

$.ecity.changeWord = function(str) {
  var words = null;
  if (window.dictWords) {
    words = window.dictWords;
  } else if ($.ecity.top && $.ecity.top.dictWords) {
    words = $.ecity.top.dictWords;
  } else {
    $.ecity.getDictWords();
    words = window.dictWords;
  }
  return typeof words[str] === 'undefined' ? str : words[str];
};

$.ecity.getDictWords = function() {
  var language = $.ecity.getPageParam('lang');
  if (!language) {
    window.dictWords = {};
    return;
  }
  // 2019-06-10 获取当前的语言信息，和 init.xml 中的进行匹配，如果非法，需要强制转换
  // var defalutLang = $.ecity.top.$.ecity.frame.sysCfg.data.init.defaultLang;
  // console.log(defalutLang);

  var file = $.ecity.rootpath + '/cfg/lang/text-' + language + '.json';
  var ajaxOptions = {
    url: file,
    dataType: 'json',
    async: false,
    timeout: 500,
    success: function(res) {
      try {
        if (typeof res == 'string') {
          res = JSON.parse(res);
        }
        window.dictWords = res;
      } catch (e) {
        console.error(file + '文件不是标准json格式');
        console.error(e.message);
        throw new Error(file + '文件不是标准json格式');
      }
    },
    error: function(res) {
      console.log('获取' + file + '失败！');
    },
  };
  $.ajax(ajaxOptions);
};
$(document).ready(function() {
  var words = null;
  if (window.dictWords) {
    words = window.dictWords;
  } else if ($.ecity.top && $.ecity.top.dictWords) {
    words = $.ecity.top.dictWords;
  } else {
    $.ecity.getDictWords();
    words = window.dictWords;
  }
  $('[data-localize]').localize('text', {
    pathPrefix: 'cfg/lang',
    language: $.ecity.getPageParam('lang') || 'zh_CN',
    dictWords: words,
  });
});

// 覆写 $.ajax，已实现 token 自动传递
const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队（异步任务）。',
  204: '删除数据成功。',
  400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限（令牌、用户名、密码错误）。',
  403: '用户得到授权，但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除，且不会再得到的。',
  422: '当创建一个对象时，发生一个验证错误。',
  500: '服务器发生错误，请检查服务器。',
  502: '网关错误。',
  503: '服务不可用，服务器暂时过载或维护。',
  504: '网关超时。',
};
var originAjax = $.ajax;

$.ajax = function(url, options) {
  // If url is an object, simulate pre-1.5 signature
  if (typeof url === 'object') {
    options = url;
    url = undefined;
  }

  // Force options to be an object
  options = options || {};

  if (typeof url === 'string' && typeof options.url !== 'string') {
    options.url = url;
  }

  if ($.ecity.top.g_ctx && typeof $.ecity.top.g_ctx.logout === 'function') {
    options.url = getNextUrlWithToken(options.url);

    // 覆写 error 部分
    var originError = options.error;
    options.error = function(xhr, textStatus, errorThrown) {
      if (xhr.status === 401) {
        $.ecity.top.g_ctx.logout();
      } else if (typeof originError === 'function') {
        originError(xhr, textStatus, errorThrown);
      }
    };
  }

  return originAjax(options);
};

function getNextUrlWithToken(url) {
  if (url.indexOf('access_token') > -1) {
    return url;
  }
  if (!$.ecity.top.g_ctx || typeof $.ecity.top.g_ctx.getToken !== 'function') {
    return url;
  }
  let preUrl = '';
  let newUrl = url;
  // 针对 proxy.jsp 做特殊处理
  const proxyIndex = newUrl.indexOf('proxy.jsp');
  if (proxyIndex > -1) {
    preUrl = newUrl.substring(0, proxyIndex + 10);
    newUrl = newUrl.substring(proxyIndex + 10);
  }

  if (newUrl.indexOf('?') === -1) {
    newUrl += '?';
  } else {
    if (newUrl.indexOf('?') !== newUrl.length - 1) {
      newUrl += '&';
    }
  }
  newUrl += 'access_token=' + $.ecity.top.g_ctx.getToken();
  return preUrl + newUrl;
}
